package classLoader;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;


public class ClassUtils {

	final static Map<String, Object> instanceMap = new HashMap<String, Object>();
	final static Map<String, Class> classMap = new HashMap<String, Class>();

	static Logger logger = Logger.getLogger(ClassUtils.class);

	
	/**
	 * 根据路径获得该java类的包名
	 * @param classPath
	 * @return
	 * @throws IOException
	 */
	public static String getClassPackage(String classPath) throws IOException
	{
		InputStream in = new FileInputStream(classPath);
		BufferedReader reader = new BufferedReader(new InputStreamReader(in)) ;
		String packageName ="";
		try
		{
			//截取包名
			String line="";
			while((line=reader.readLine())!=null)
			{
				if(line.indexOf("package")!=-1)
				{
					//package logic.scene; 变成 logic.scene
					packageName = line.substring(line.indexOf(" "),line.length()-1).trim();
					break;
				}
			}
		}
		finally
		{
			reader.close();
			in.close();
		}
		return packageName;
	}
	
	//
	
	/**
	 * 截取一个继承类的名字
	 * 例如 ：public class CallBackResponse extends Response
	 * 截取了 CallBackResponse
	 * @param classPath
	 * @return
	 * @throws IOException
	 */
	public static String getExtendsClassName(String classPath,String spuerClassName) throws IOException
	{
		InputStream in = new FileInputStream(classPath);
		BufferedReader reader = new BufferedReader(new InputStreamReader(in)) ;
		String name = null;
		try
		{
			String line="";
			while((line=reader.readLine())!=null)
			{
				if(line.indexOf(spuerClassName)!=-1&&line.indexOf("extends")!=-1)
				{
					name = line.substring(line.indexOf("class")+5, line.indexOf("extends")).trim();
					break;
				}
			}
		}
		finally
		{
			reader.close();
			in.close();
		}
		return name;
	}
	
	
	
	
	public static void setFieldValue(Object target, String fieldName,
			Object object) {
		Class clazz = target.getClass();
		Field field = null;
		try {
			field = clazz.getField(fieldName);
		} catch (Exception e) {
		}
		if (field != null) {
			field.setAccessible(true);
			try {
				field.set(target, object);
			} catch (Exception e) {
			}
		}
	}

	public static void copyFieldValue(Object src, Object dest) {
		Map<String, Field> srcFields = getFields(src.getClass());
		Map<String, Field> destFields = getFields(dest.getClass());
		Iterator<String> srcIt = srcFields.keySet().iterator();
		while (srcIt.hasNext()) {
			String key = srcIt.next();
			Field srcField = srcFields.get(key);
			Field destField = destFields.get(key);
			if (destField != null) {
				// 无视防御。。。
				destField.setAccessible(true);
				srcField.setAccessible(true);

				try {
					destField.set(dest, srcField.get(src));
				} catch (Exception e) {

				}
			}
		}
	}

	public static Map<String, Field> getFields(Class clazz) {
		Field[] fields = clazz.getDeclaredFields();
		Map<String, Field> map = new HashMap<String, Field>();
		for (Field field : fields) {
			Class fieldClass = field.getType();
			String name = field.getName();

			String key = fieldClass.getName() + "." + name;
			map.put(key, field);
		}
		return map;
	}

	public static void close(Object... objects) {
		if (objects == null || objects.length < 1) {
			return;
		}
		for (Object object : objects) {
			if (object == null) {
				continue;
			}

			Class clazz = object.getClass();
			try {
				Method method = clazz.getMethod("close");
				method.invoke(object);
			} catch (Exception e) {
				logger.error("close {} fail!", e);
			}
		}

	}


	public static Class getClass(String clazz) {
		Class classObject = classMap.get(clazz);
		if (classObject == null) {
			try {
				classObject = Class.forName(clazz);
				classMap.put(clazz, classObject);
			} catch (Exception e) {
				logger.error("not found classs {}", e);
			}
		}
		return classObject;
	}

	public static <T extends Object> T newSingleInstance(String clazz)
			throws ClassNotFoundException {
		Object object = instanceMap.get(clazz);
		if (object == null) {
			try {
				Class objectClass = getClass(clazz);
				if (objectClass != null) {
					object = objectClass.newInstance();
					instanceMap.put(clazz, object);
				}

			} catch (Exception e) {
				logger.error("instance {} fail", e);
			}
		}
		return (T) object;
	}

	public static void listFields(Class clazz) {
		clazz.getDeclaredFields();
	}

}
